﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetfractionHub.Network.Protocol;
using NetfractionHub.Network.Protocol.BASE.Factory;

namespace NetfractionHub.LocalMachine.BotCommands.Handler
{
    [CommandHandler("role")]
    public class Role : CommandHandler
    {
        public override BotReturnStatus HandleCommandMessage(NetfractionHub.RemoteMachine.Node source, CommandMessage message)
        {
            if (message.StringArguments.Count == 1)
            {
                if (message.StringArguments.ContainsKey("user"))
                    return SendRoleOfIdentity(source, message.StringArguments["user"]);
            }
            else if (message.StringArguments.Count == 2)
            {
                if (!message.StringArguments.ContainsKey("user"))
                    return new BotReturnStatus(false, "Missing argument 'user'.");

                if (!message.StringArguments.ContainsKey("set"))
                    return new BotReturnStatus(false, "Missing argument 'set'.");

                return SetRoleOfIdentity(source, message.StringArguments["user"], message.StringArguments["set"]);
            }
            else if (message.UnnamedArguments.Count == 1)
            {
                return SendRoleOfIdentity(source, message.UnnamedArguments[0]);
            }
            else
            {
                return SendRoleOfIdentity(source, source.Identity.Nickname);
            }

            return new BotReturnStatus(true);
        }

        private BotReturnStatus SendRoleOfIdentity(NetfractionHub.RemoteMachine.Node source, string username)
        {
            RemoteMachine.Node user = Network.ConnectionManager.GetConnectedNodeByNickname(username);

            if (user == null)
                return new BotReturnStatus(false, string.Format("The user '{0}' does not exist.", username));

            if (user.SessionId == source.SessionId)
                if (Security.Permission.HasPermission(source.SecurityIdentity, typeof(Security.Permissions.ListOwnIdentityPermissionsPermission)))
                    return new BotReturnStatus(true, string.Format("Your role is '{0}'.", user.SecurityIdentity.Role.Name));
                else
                    return new BotReturnStatus(false, Security.Permission.GetDeniedString(typeof(Security.Permissions.ListOwnIdentityPermissionsPermission)));
            else if (Security.Permission.HasPermission(source.SecurityIdentity, typeof(Security.Permissions.ListIdentityPermissionsPermission)))
                if (Security.RoleManager.IsInAncestorTree(source.SecurityIdentity.Role, user.SecurityIdentity.Role))
                    return new BotReturnStatus(true, string.Format("The user '{0}' has the role '{1}'.", username, user.SecurityIdentity.Role.Name));
                else
                    return new BotReturnStatus(false, string.Format("Permission denied. You are not an ancestor of '{0}'.", username));
            else
                return new BotReturnStatus(false, Security.Permission.GetDeniedString(typeof(Security.Permissions.ListIdentityPermissionsPermission)));
        }

        private BotReturnStatus SetRoleOfIdentity(NetfractionHub.RemoteMachine.Node source, string username, string roleName)
        {
            RemoteMachine.Node user = Network.ConnectionManager.GetConnectedNodeByNickname(username);

            if (user == null)
                return new BotReturnStatus(false, string.Format("The user '{0}' does not exist.", username));

            Security.Role newRole = Security.RoleManager.GetRoleByName(roleName);

            if (newRole == null)
                return new BotReturnStatus(false, string.Format("The role '{0}' does not exist.", roleName));

            if (!Security.Permission.HasPermission(source.SecurityIdentity, typeof(Security.Permissions.SetRolePermission)))
                return new BotReturnStatus(false, Security.Permission.GetDeniedString(typeof(Security.Permissions.ListIdentityPermissionsPermission)));

            if (Security.RoleManager.IsInAncestorTree(source.SecurityIdentity.Role, user.SecurityIdentity.Role))
            {
                user.SecurityIdentity.Role = newRole;   // TODO: this may set the role, but will it persist it??
                this.ParentBot.SendEchoMessageFromBot(source, string.Format("The role of user '{0}' is now '{1}'.", username, roleName));
            }
            else
                return new BotReturnStatus(false, string.Format("Permission denied. You are not an ancestor of '{0}'.", username));
            
            return new BotReturnStatus(true);
        }
    }
}
